#import "TencentCos.h"
//#import <QCloudCore/MTAConfig.h>
#import <QCloudCOSXML/QCloudCOSXML.h>

@interface TencentCos () <QCloudSignatureProvider, QCloudCredentailFenceQueueDelegate>
@property (nonatomic, strong)QCloudServiceConfiguration* configuration;
@property (nonatomic, strong)QCloudCOSXMLEndPoint* endPoint;
@property (nonatomic, strong)NSString* appId;
@property (nonatomic, strong)NSString* signUrl;
@property (nonatomic, strong)NSString* cookie;
@property (nonatomic, strong)NSString* bucket;
@property (nonatomic, strong)NSString* region;
@property (nonatomic)NSInteger systemId;
@end

@interface TencentCos () <QCloudSignatureProvider>

@end

@implementation TencentCos
static QCloudCredentailFenceQueue* credentialFenceQueue = nil;
RCT_EXPORT_MODULE()

- (void) fenceQueue:(QCloudCredentailFenceQueue *)queue requestCreatorWithContinue:(QCloudCredentailFenceQueueContinue)continueBlock
{
  QCloudHTTPRequest* request = [QCloudHTTPRequest new];
  request.requestData.serverURL = self.signUrl;
  //request.requestData.stringEncoding = NSUTF8StringEncoding;
  NSString *s = self.cookie;
  if(!([s isKindOfClass:[NSNull class]] || s == nil || [s isEqualToString:@""])) {
    [request.requestData setValue:self.cookie forHTTPHeaderField:@"authorization"];
  }
  
  request.requestSerializer.HTTPMethod = HTTPMethodPOST;
  request.requestSerializer.useCookies = NO;
  request.requestSerializer.shouldAuthentication = NO;
  
  [request.requestData setParameter:[NSString stringWithFormat:@"%@-%@", self.bucket, self.appId] withKey:@"bucket"];
  [request.requestData setParameter:self.region withKey:@"region"];
  if(self.systemId > 0)
  {
    [request.requestData setParameter:@(self.systemId) withKey:@"systemId"];
  }
  
  [request setConfigureBlock:^(QCloudRequestSerializer *requestSerializer, QCloudResponseSerializer *responseSerializer) {
    requestSerializer.serializerBlocks = @[QCloudURLFuseSimple,QCloudURLFuseWithJSONParamters];
    responseSerializer.serializerBlocks = @[QCloudAcceptRespnseCodeBlock([NSSet setWithObjects:@(200), nil], nil),
                                            QCloudResponseJSONSerilizerBlock];
  }];
  void(^NetworkCall)(id response, NSError* error) = ^(id response, NSError* error) {
    if (error) {
      continueBlock(nil, error);
    } else {
      NSInteger code  = [response[@"status"] integerValue];
      if (response[@"status"] && code == 0) {
        QCloudCredential* crendential = [[QCloudCredential alloc] init];
        crendential.secretID = response[@"data"][@"credentials"][@"tmpSecretId"];
        crendential.secretKey = response[@"data"][@"credentials"][@"tmpSecretKey"];
        NSTimeZone *timeZone = [NSTimeZone systemTimeZone];
        NSInteger delta = [timeZone secondsFromGMT];
        crendential.expirationDate = [NSDate dateWithTimeIntervalSince1970:([response[@"data"][@"expiredTime"] intValue] + delta)];
        crendential.expirationDate = [NSDate dateWithTimeIntervalSince1970:[response[@"data"][@"expiredTime"] intValue]];
        NSLog(@"\n过期时间 %@\n当前时间%@",crendential.expirationDate,[NSDate date]);
        crendential.token = response[@"data"][@"credentials"][@"sessionToken"];
        QCloudAuthentationV5Creator* creator = [[QCloudAuthentationV5Creator alloc] initWithCredential:crendential];
        continueBlock(creator, nil);
      } else {
        error = [NSError errorWithDomain:@"com.tac.test" code:-1111 userInfo:@{NSLocalizedDescriptionKey:@"Credentials is null"}];
        continueBlock(nil, error);
      }
      
    }
  };
  
  [request setFinishBlock:NetworkCall];
  [[QCloudHTTPSessionManager shareClient] performRequest:request];
}

- (void) signatureWithFields:(QCloudSignatureFields*)fileds
                     request:(QCloudBizHTTPRequest*)request
                  urlRequest:(NSMutableURLRequest*)urlRequst
                   compelete:(QCloudHTTPAuthentationContinueBlock)continueBlock
{
  [credentialFenceQueue performAction:^(QCloudAuthentationCreator *creator, NSError *error) {
    if (error) {
      continueBlock(nil, error);
    } else {
      QCloudSignature* signature =  [creator signatureForData:urlRequst];
      continueBlock(signature, nil);
    }
  }];
}

RCT_EXPORT_METHOD(upload:(NSString *)originLocalPath
                    CosPath:(NSString *)originCosPath
                    resolver:(RCTPromiseResolveBlock)resolve
                    rejecter:(RCTPromiseRejectBlock)reject)
{
  dispatch_async(dispatch_get_main_queue(), ^{
    if(self.configuration == nil) {
      resolve(@-1);
      return;
    }
    QCloudCOSXMLUploadObjectRequest* put = [QCloudCOSXMLUploadObjectRequest new];
    NSURL* url = [NSURL fileURLWithPath:originLocalPath] /*文件的URL*/;
    
    put.object = [NSString stringWithFormat:@"%@%.0f%@", originCosPath, [[NSDate date] timeIntervalSince1970], [originLocalPath lastPathComponent] ];
    put.bucket = [NSString stringWithFormat:@"%@-%@", self.bucket, self.appId ];
    put.body =  url;
    [put setSendProcessBlock:^(int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend) {
        NSLog(@"upload %lld totalSend %lld aim %lld", bytesSent, totalBytesSent, totalBytesExpectedToSend);
    }];
    [put setFinishBlock:^(id outputObject, NSError* error) {
      dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(@"upload over");
        if(error) {
          reject(nil,nil,error);
        } else {
          resolve(((QCloudUploadObjectResult*)outputObject).location);
        }
      });
    }];
    [[QCloudCOSTransferMangerService defaultCOSTransferManager] UploadObject:put];
  });
}

RCT_EXPORT_METHOD(uploadWithName:(NSString *)originLocalPath
                    CosPath:(NSString *)originCosPath
                    resolver:(RCTPromiseResolveBlock)resolve
                    rejecter:(RCTPromiseRejectBlock)reject)
{
  dispatch_async(dispatch_get_main_queue(), ^{
    if(self.configuration == nil) {
      resolve(@-1);
      return;
    }
    QCloudCOSXMLUploadObjectRequest* put = [QCloudCOSXMLUploadObjectRequest new];
    NSURL* url = [NSURL fileURLWithPath:originLocalPath] /*文件的URL*/;
    
    put.object = [NSString stringWithFormat:@"%@", originCosPath ];
    put.bucket = [NSString stringWithFormat:@"%@-%@", self.bucket, self.appId ];
    put.body =  url;
    [put setSendProcessBlock:^(int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend) {
        NSLog(@"upload %lld totalSend %lld aim %lld", bytesSent, totalBytesSent, totalBytesExpectedToSend);
    }];
    [put setFinishBlock:^(id outputObject, NSError* error) {
      dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(@"upload over");
        if(error) {
          reject(nil,nil,error);
        } else {
          resolve(((QCloudUploadObjectResult*)outputObject).location);
        }
      });
    }];
    [[QCloudCOSTransferMangerService defaultCOSTransferManager] UploadObject:put];
  });
}

RCT_EXPORT_METHOD(initCosService:(NSString *)appid
                    Bucket:(NSString *)bucket
                    Region:(NSString *)region
                    Cookie:(NSString *)cookie
                    SignUrl:(NSString*)signUrl
                    SystemId:(NSInteger)systemId
                    resolver:(RCTPromiseResolveBlock)resolve
                    rejecter:(RCTPromiseRejectBlock)reject)
{
    self.appId = appid;
    self.signUrl = signUrl;
    self.cookie = cookie;
    self.bucket = bucket;
    self.region = region;
    self.systemId = systemId;
    if(self.configuration == nil) {
        self.configuration = [QCloudServiceConfiguration new];
    }
    self.configuration.appID = appid;
    self.configuration.signatureProvider = self;
    if(self.endPoint == nil) {
        self.endPoint = [[QCloudCOSXMLEndPoint alloc] init];
    }
    self.endPoint.regionName = region;//服务地域名称，可用的地域请参考注释
    self.configuration.endpoint = self.endPoint;
    if([QCloudCOSXMLService hasServiceForKey:region]) {
        [QCloudCOSXMLService removeCOSXMLWithKey:region];
    }
    [QCloudCOSXMLService registerCOSXMLWithConfiguration:self.configuration withKey:region];
    [QCloudCOSTransferMangerService registerDefaultCOSTransferMangerWithConfiguration:self.configuration];
    if(credentialFenceQueue == nil) {
        credentialFenceQueue = [QCloudCredentailFenceQueue new];
        credentialFenceQueue.delegate = self;
    }
    //[TACMTAConfig getInstance].statEnable = NO;
    resolve(@"success");
}

@end
